package org.andromeo;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Messenger;
import android.os.RemoteException;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

/**
 * creates a friendlist
 * 
 * @author fabian
 * 
 */

public class VisitorlistActivity extends ListActivity {
	/** Called when the activity is first created. */
	ListView listview = null;

	private GRSession grsession;
	ArrayAdapter<User> userlistAdapter;

	ProgressDialog mProgDialog;

	long nextUserListExtractionTime;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		grsession = ((ARApplication) getApplication()).getGrsession();

		// setContentView(R.layout.friendlist);
		// listview = (ListView) findViewById(R.id.friendlistview);

		listview = getListView();

		/**
		 * create list adapter and assign it with listview
		 */
		userlistAdapter = getVisitorListAdapter();
		listview.setAdapter(userlistAdapter);

		/**
		 * set background
		 */
		listview.setBackgroundDrawable((this.getResources()
				.getDrawable(R.drawable.solid_blue_bg)));
		listview.setCacheColorHint(this.getResources().getColor(
				R.drawable.color_transparent));

		/**
		 * build progess dialog
		 */
		mProgDialog = new ProgressDialog(VisitorlistActivity.this);
		mProgDialog.setTitle(R.string.working);
		mProgDialog.setMessage(getString(R.string.pull_friendlist));
		mProgDialog.setIndeterminate(true);
		mProgDialog.setCancelable(false);

		// Initialer Start der App.
		mHandler.post(visitorsExtractionRunnable);

	}

	private ArrayAdapter<User> getVisitorListAdapter() {

		return new ArrayAdapter<User>(this,
				android.R.layout.simple_list_item_1, new Vector<User>()) {

			ArrayAdapter<User> thisUserAdapter = this;

			/*
			 * 
			 * (non-Javadoc)
			 * 
			 * @see android.widget.ArrayAdapter#getView(int, android.view.View,
			 * android.view.ViewGroup)
			 */
			@Override
			public View getView(int position, View convertView, ViewGroup parent) {

				/*
				 * User item to display
				 */
				User vUser;

				ImageView imageItemView;
				ImageView footprintItemView;
				TextView usernameItemView;
				TextView statusItemView;
				View vView = convertView;

				if (vView == null) {
					LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
					vView = vi.inflate(R.layout.visitorlistitem, null);
				}
				imageItemView = (ImageView) vView
						.findViewById(R.id.userListItemImage);
				footprintItemView = (ImageView) vView
						.findViewById(R.id.userListFootprintImage);
				usernameItemView = (TextView) vView
						.findViewById(R.id.userListItemUserName);
				statusItemView = (TextView) vView
						.findViewById(R.id.userListItemOnlineStatus);

				vUser = thisUserAdapter.getItem(position);

				if (vUser.getUserName() != null) {
					usernameItemView.setText(vUser.getUserName());
				} else {
					usernameItemView.setText("ERROR USERNAME");
				}

				if (vUser.getOnlineStatus() != null) {
					statusItemView.setText(vUser.getOnlineStatus());
				} else {
					statusItemView.setText("???");
				}

				String vThumbnailURL = vUser.getThumbnailImageURL();
				String vFootprintURL = vUser.getRecFootprintURL();

				if (vThumbnailURL != null && vThumbnailURL.length() > 0)
					try {
						addImageToThumbnail(vThumbnailURL, imageItemView);
					} catch (Exception e1) {
						e1.printStackTrace();
					}
				else
					imageItemView
							.setImageResource(R.drawable.andromeostandardusericon);

				Bitmap bm = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
				footprintItemView.setImageBitmap(bm);

				if (vFootprintURL != null && vFootprintURL.length() > 0)
					try {
						addImageToThumbnail(vFootprintURL, footprintItemView);
						footprintItemView.setVisibility(View.VISIBLE);
					} catch (Exception e) {
						e.printStackTrace();
					}

				return vView;
			}

			private void addImageToThumbnail(String pUrl, ImageView pImageView) {

				try {
					Bitmap bm;
					URL aURL = new URL(pUrl);
					URLConnection conn = aURL.openConnection();
					conn.connect();
					InputStream is = conn.getInputStream();
					BufferedInputStream bis = new BufferedInputStream(is);
					bm = BitmapFactory.decodeStream(bis);
					bis.close();
					is.close();

					pImageView.setImageBitmap(bm);

					// pImageView.setOnClickListener(new OnClickListener() {
					//						
					// @Override
					// public void onClick(View v) {
					// Intent i = new Intent(WriteMessageActivity.this,
					// ImageActivity.class);
					// i.putExtra(ImageActivity.LINK, link);
					// startActivity(i);
					//						
					// }
					// });

				} catch (IOException e) {
					e.printStackTrace();
				}

			}

		};
	}

	@Override
	protected void onStart() {
		// TODO Auto-generated method stub
		super.onStart();
		doBindService();
		mHandler.post(visitorsExtractionRunnable);
	}

	/**
	 * Currently restarts the timer when activity is recalled Checks
	 * 
	 * @params none
	 * @returns none
	 */
	@Override
	protected void onRestart() {
		// TODO Auto-generated method stub
		super.onRestart();
		userlistAdapter.notifyDataSetChanged();
	}

	@Override
	protected void onStop() {
		doUnbindService();
		super.onStop();
	}

	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		// TODO Auto-generated method stub
		super.onListItemClick(l, v, position, id);

		Intent msgintent = new Intent(Intent.ACTION_CALL);
		msgintent.setClassName(ViewFriendActivity.class.getPackage().getName(),
				ViewFriendActivity.class.getName());

		msgintent.putExtra(ViewFriendActivity.KEY_USERID, userlistAdapter
				.getItem(position).getUserID());

		startActivityForResult(msgintent, 0);

	}

	Handler mHandler = new Handler();

	private int userlistExtractionInterval = 5 * 60 * 1000;

	/*
	 * get the friendlists by instancing and executing GetFriendlistTask
	 */
	private Runnable visitorsExtractionRunnable = new Runnable() {
		@Override
		public void run() {
			new GetFriendlistTask().execute(grsession);
		}
	};

	/**
	 * as recommenend, we're using AsyncTask for correct UI-calling
	 */

	private class GetFriendlistTask extends
			AsyncTask<GRSession, Integer, Integer> {

		List<User> workinglist;

		@Override
		protected void onPreExecute() {
			// TODO Auto-generated method stub
			super.onPreExecute();
			if (userlistAdapter.isEmpty())
				mProgDialog.show();
			else
				Toast.makeText(
						VisitorlistActivity.this,
						VisitorlistActivity.this
								.getString(R.string.pull_friendlist),
						Toast.LENGTH_LONG).show();
		}

		@Override
		protected Integer doInBackground(GRSession... arg0) {
			// TODO implement exception handling
			try {
				workinglist = grsession.getUserFactory().getVisitorlist();
			} catch (ARException e) {
				e.printStackTrace();
			}
			return 0;
		}

		@Override
		protected void onPostExecute(Integer result) {
			// TODO implement exception handling

			if (workinglist != null){
				userlistAdapter.clear();
				for (Iterator<User> it = workinglist.iterator(); it.hasNext();) {
					userlistAdapter.add(it.next());
				}
			}
			mProgDialog.dismiss();
		}

	};

	@Override
	protected void onDestroy() {
		super.onDestroy();
		mHandler.removeCallbacks(visitorsExtractionRunnable);
	};

	// Some code for handling

	boolean mIsBound = false;

	// remote messenger
	Messenger rMessenger = null;

	/**
	 * This handler receives a message when the underlying dataset has changed
	 */
	private Handler incomingHandler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			if (msg.what == HeartbeatService.ANDROIDMSG_DATASET_CHANGED) {
				mHandler.post(visitorsExtractionRunnable);
			}
		};
	};

	private android.os.Messenger messenger = new android.os.Messenger(
			incomingHandler);

	private ServiceConnection servConn = new ServiceConnection() {

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			try {
				rMessenger = new Messenger(service);
				android.os.Message amsg = android.os.Message.obtain(
						incomingHandler,
						HeartbeatService.ANDROIDMSG_REGISTER_HANDLER);
				amsg.replyTo = messenger;
				rMessenger.send(amsg);
			} catch (RemoteException e) {
				e.printStackTrace();
			}
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {
			// currently does nothing
		}

	};

	void doBindService() {
		// bindService must be called via getApplicationcontext, otherwise no
		// bind will be executed!
		mIsBound = getApplicationContext().bindService(
				new Intent(this, HeartbeatService.class), servConn, 0);

	}

	void doUnbindService() {
		if (mIsBound) {
			// If we have received the service, and hence registered with
			// it, then now is the time to unregister.
			if (rMessenger != null) {
				try {
					android.os.Message msg = android.os.Message.obtain(null,
							HeartbeatService.ANDROIDMSG_UNREGISTER_HANDLER);
					msg.replyTo = messenger;
					rMessenger.send(msg);
				} catch (RemoteException e) {
					// There is nothing special we need to do if the service
					// has crashed.
				}
			}

			// Detach our existing connection.
			getApplicationContext().unbindService(servConn);
			mIsBound = false;
		}
	}

}
